package com.spring.demos.ioccontainer.dao.impl;

import com.alibaba.druid.pool.DruidDataSource;
import com.spring.demos.ioccontainer.dao.FixedDepositDao;
import com.spring.demos.ioccontainer.pojo.FixedDepositDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


@Repository("fixedDepositDao")
public class FixedDepositDaoImpl implements FixedDepositDao {


    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setJdbcTemplate(DruidDataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void saveDepositDetail(FixedDepositDetails fixedDepositDetails) {
        final String sql = "insert into fixed_deposit_detail(account_num,username,balance_amount,email,"
                +"updated_time,updated_by)values(?,?,?,?,?,?)";
        jdbcTemplate.update(sql,new Object[]{fixedDepositDetails.getAccountNum(),
                fixedDepositDetails.getUsername(), fixedDepositDetails.getBalanceAmount(),
                fixedDepositDetails.getEmail(),fixedDepositDetails.getUpdatedTime(),fixedDepositDetails.getUpdatedBy()});
    }

    @Override
    public int[] batchSaveDepositDetail(List<FixedDepositDetails> depositDetails) {
        final String sql = "insert into fixed_deposit_detail(account_num,username,balance_amount,email,"
                +"updated_time,updated_by)values(?,?,?,?,?,?)";

        BatchPreparedStatementSetter statementSetter = new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                FixedDepositDetails fixedDepositDetails = depositDetails.get(i);
                ps.setString(1,fixedDepositDetails.getAccountNum());
                ps.setString(2,fixedDepositDetails.getUsername());
                ps.setFloat(3,fixedDepositDetails.getBalanceAmount());
                ps.setString(4,fixedDepositDetails.getEmail());
                ps.setString(5,fixedDepositDetails.getUpdatedTime());
                ps.setString(6,fixedDepositDetails.getUpdatedBy());

            }

            @Override
            public int getBatchSize() {
                return depositDetails.size();
            }
        };

        return jdbcTemplate.batchUpdate(sql,statementSetter);
    }

    @Override
    public FixedDepositDetails queryDepositById(String accountNum) {
        final String sql = "select account_num,username,balance_amount,"
                +"email,updated_time,updated_by "
                +"from fixed_deposit_detail where account_num=?";
        FixedDepositDetails fixedDepositDetails = jdbcTemplate.queryForObject(sql, new Object[]{accountNum},new RowMapper<FixedDepositDetails>() {
            @Override
            public FixedDepositDetails mapRow(ResultSet rs, int i) throws SQLException {
                FixedDepositDetails fixedDepositDetails1 = new FixedDepositDetails();
                fixedDepositDetails1.setAccountNum(rs.getString("account_num"));
                fixedDepositDetails1.setUsername(rs.getString("username"));
                fixedDepositDetails1.setBalanceAmount(rs.getFloat("balance_amount"));
                fixedDepositDetails1.setEmail(rs.getString("email"));
                String dateTimeStr = sdf.format(rs.getDate("updated_time"));
                fixedDepositDetails1.setUpdatedTime(dateTimeStr);
                fixedDepositDetails1.setUpdatedBy(rs.getString("updated_by"));
                return fixedDepositDetails1;
            }
        });

        return fixedDepositDetails;
    }

    @Override
    public void deleteDepositById(String accountNum) {

        final String sql = "delete from fixed_deposit_detail where account_num=?";

        jdbcTemplate.update(sql,accountNum);

    }

    @Override
    public void saveMoney(String accountNum, float money) {

        FixedDepositDetails fixedDepositDetails = checkAndGetDepositDetails(accountNum);

        fixedDepositDetails.setBalanceAmount(fixedDepositDetails.getBalanceAmount()+money);

        updateMoney(fixedDepositDetails);

    }

    @Override
    public void getMoney(String accountNum, float money) {
        FixedDepositDetails fixedDepositDetails = checkAndGetDepositDetails(accountNum);
        if(fixedDepositDetails.getBalanceAmount()<money){
            throw  new IllegalArgumentException("the balance money is less than "+money);
        }
        fixedDepositDetails.setBalanceAmount(fixedDepositDetails.getBalanceAmount()-money);

        updateMoney(fixedDepositDetails);
    }

    private void updateMoney(FixedDepositDetails fixedDepositDetails){
        final String sql = "update fixed_deposit_detail set balance_amount=?,updated_time=?"
                +" where account_num=?";
        String updatedTime = sdf.format(new Date());
        jdbcTemplate.update(sql,Float.valueOf(fixedDepositDetails.getBalanceAmount()),updatedTime,fixedDepositDetails.getAccountNum());
    }
    //检查账户是否存在
    private FixedDepositDetails checkAndGetDepositDetails(String accountNum){
        FixedDepositDetails fixedDepositDetails = queryDepositById(accountNum);
        if(fixedDepositDetails==null){
            throw new NullPointerException("there's no fixedDepositDetails whose accountNum="+accountNum);
        }
        return fixedDepositDetails;
    }

}
